package com.sz.dao.impl;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.junit.Test;

import com.sz.pojo.User;

public class MySql {
	// 创建jdbc对象
	public static Connection con = null;
	public static Statement st = null;
	public static PreparedStatement ps = null;
	public static ResultSet rs = null;

	// 创建变量
	private static String sqlUrl = null;
	private static String sqlUser = null;
	private static String sqlPwd = null;

	/**
	 * 获取属性文件 db.properties 的数据库信息
	 * 
	 * @throws IOException
	 */
	public static void getPro() throws IOException {
		InputStream in = MySql.class.getResourceAsStream("/db.properties");
		Properties p = new Properties();
		p.load(in);
		sqlUrl = p.getProperty("sqlUrl");
		sqlUser = p.getProperty("sqlUser");
		sqlPwd = p.getProperty("sqlPwd");
	}

	// private static final String sqlUrl =
	// "jdbc:mysql://localhost:3306/my_servletjsptest";
	// private static final String sqlUser = "root";
	// private static final String sqlPwd = "123456";

	// 返回Connection对象的实例
	/**
	 * 获取连接数据库的连接类
	 * 
	 * @return Connection类型
	 */
	public static Connection getCon() {
		if (con == null) {
			try {
				MySql.getPro();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			try {
				// 加载驱动
				Class.forName("com.mysql.jdbc.Driver");
				// 连接shujuk
				try {
					con = DriverManager.getConnection(sqlUrl, sqlUser, sqlPwd);
				} catch (SQLException e) {
					e.printStackTrace();
				}
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
		return con;
	}

	User u = null;

	@Test
	public void t2() {
		u = new User();
		System.out.println("-----------");
		System.out.println(this.queryAuto(u, "select * from user where id=2"));
	}

	/**
	 * 自动将查询到的数据赋值给pojo对象实例（多条数据）
	 * 
	 * @param <T>       泛型
	 * @param object    pojo对象
	 * @param sql       查询语句
	 * @param parameter 查询语句的参数
	 * @return
	 */
	public static List queryAutoMany(Object object, String sql, Object... parameter) {
		List<Object> uu = new ArrayList<Object>();
		Field[] d = null;
		try {
			d = Class.forName(object.getClass().getName()).getDeclaredFields();
		} catch (SecurityException | ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		}
		// 获取查询到的数据
		ResultSet rs = MySql.query(sql, parameter);
		if (rs != null) {
			try {
				// 光标移到最后一行
				rs.last();
				// 判断行的总数
				int count = rs.getRow();
				// 返回第一行之前
				rs.beforeFirst();
				// System.out.println(count);
				if (count == 1) {
					System.out.println("有多条数据，请调用queryAuto方法");
				} else if (count > 1) {
					while (rs.next()) {
						System.out.println(rs.getObject(1) + ".---." + rs.getObject(2));
						Object add = Class.forName(object.getClass().getName()).newInstance();
						for (Field ff : d) {
							ff.setAccessible(true);
							try {
								String c = ff.getType().getName();
								ff.set(add, TypeChange.typeString(c, rs.getObject(ff.getName())));
							} catch (IllegalArgumentException | IllegalAccessException e) {
								e.printStackTrace();
							}
						}
						System.out.println(add);
						uu.add(add);
					}
				}

			} catch (SQLException e1) {
				e1.printStackTrace();
			} catch (InstantiationException e1) {
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (ClassNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		} else {
			System.out.println("queryAutoMany--方法查询数据失败。。。");
			return null;
		}

		return uu;
	}

	/**
	 * 自动将查询到的数据赋值给pojo对象实例（单条数据）
	 * 
	 * @param <T>       泛型
	 * @param object    pojo对象
	 * @param sql       查询语句
	 * @param parameter 查询语句的参数
	 * @return
	 */
	public static <T> T queryAuto(T object, String sql, Object... parameter) {
		T uu = null;
		try {
			// 新建一个pojo对象
			uu = (T) Class.forName(object.getClass().getName()).newInstance();
			// 获取pojo对象的属性
			Field[] d = uu.getClass().getDeclaredFields();
			// 获取查询到的数据
			ResultSet rs = MySql.query(sql, parameter);
			if (rs != null) {
				try {
					// 光标移到最后一行
					rs.last();
					// 判断行的总数
					int count = rs.getRow();
					// 返回第一行之前
					rs.beforeFirst();
					// System.out.println(count);
					if (count == 1) {
						while (rs.next()) {
							System.out.println(rs.getObject(1) + ".---." + rs.getObject(2));
							for (Field ff : d) {
								ff.setAccessible(true);
								try {
									String c = ff.getType().getName();
									ff.set(uu, TypeChange.typeString(c, rs.getObject(ff.getName())));
								} catch (IllegalArgumentException | IllegalAccessException e) {
									e.printStackTrace();
								}
							}
						}
					} else if (count > 1) {
						System.out.println("有多条数据，请调用queryAutoMany方法");
					}

				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			} else {
				System.out.println("queryAuto--方法查询数据失败。。。");
				return null;
			}
		} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e2) {
			e2.printStackTrace();
		}
		return uu;
	}

	/**
	 * 查询数据库信息并返回结果集
	 * 
	 * 实例："select * from user where uname=?"
	 * 
	 * @param sql       查询语句，为prepareStatement类型
	 * @param parameter 参数，为空或任意多个
	 * @return 返回Resultset类型的结果集
	 */
	public static ResultSet query(String sql, Object... parameter) {
		MySql.getCon();
		ResultSet rs = null;
		try {
			ps = con.prepareStatement(sql);
			// ps.setMaxRows(10);
			if (parameter.length != 0) {
				for (int i = 0; i < parameter.length; i++) {
					ps.setObject(i + 1, parameter[i]);
				}
			}
			rs = ps.executeQuery();
		} catch (SQLException e) {
			e.printStackTrace();
			System.out.println("query--方法执行失败！！");
			return null;
		}
		return rs;
	}

	/**
	 * 更新或添加数据
	 * 
	 * 实例：1."UPDATE user SET age=18 where uname='李wu'"
	 * 
	 * 2."INSERT INTO user(uname, pwd) value(?, ?)", "李四", "123"
	 * 
	 * 3."inset into user(id,uname, pwd, sex, age, birth) value(default,?,?,?,?,?)"
	 * 
	 * @param sql     查询语句，为prepareStatement类型
	 * @param objects parameter 参数，为空或任意多个
	 * @return 返回int类型的结果,表示成功或失败
	 */
	public static int update(String sql, Object... parameter) {
		MySql.getCon();
		int rs = 0;
		try {
			ps = con.prepareStatement(sql);
			if (parameter.length != 0) {
				for (int i = 0; i < parameter.length; i++) {
					ps.setObject(i + 1, parameter[i]);
				}
			}
			rs = ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rs;
	}

	// 关闭连接，//关闭连接,要确认不再使用jdbc后再close，要不然下次使用使会报错，说jdbc为空指针。
	public static void close(Connection con, Statement st, ResultSet rs) throws SQLException {
		rs.close();
		st.close();
		con.close();
		MySql.closeToNull();
	}

	public static void close(Connection con, PreparedStatement ps, ResultSet rs) throws SQLException {
		rs.close();
		ps.close();
		con.close();
		MySql.closeToNull();
	}

	public static void close(Connection con, Statement st) throws SQLException {
		st.close();
		con.close();
		MySql.closeToNull();
	}

	public static void close(Connection con, PreparedStatement ps) throws SQLException {
		ps.close();
		con.close();
		MySql.closeToNull();
	}

	// ----
	public static void close(PreparedStatement ps) throws SQLException {
		ps.close();
		MySql.con.close();
		MySql.closeToNull();
	}

	public static void close(Statement st) throws SQLException {
		ps.close();
		MySql.con.close();
		MySql.closeToNull();
	}

	public static void close(PreparedStatement ps, ResultSet rs) throws SQLException {
		rs.close();
		ps.close();
		MySql.con.close();
		MySql.closeToNull();
	}

	public static void close(Statement st, ResultSet rs) throws SQLException {
		rs.close();
		ps.close();
		MySql.con.close();
		MySql.closeToNull();
	}

	public static void close(ResultSet rs) throws SQLException {
		rs.close();
		ps.close();
		MySql.con.close();
		MySql.closeToNull();
	}


	public static void closeToNull() {
		con = null;
		st = null;
		ps = null;
		rs = null;
	}
}
